package com.yenlien.traceyun.breed.service;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import com.yenlien.traceyun.business.interceptor.UserAuthUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.yenlien.traceyun.breed.dao.OrderDao;
import com.yenlien.traceyun.breed.dao.OrderDetailDao;
import com.yenlien.traceyun.breed.entity.Order;
import com.yenlien.traceyun.breed.entity.OrderDetail;
import com.yenlien.traceyun.common.utils.Tools;
import com.yenlien.traceyun.webase.exception.BusinessException;

@Service
public class OrderService {
    @Autowired
    private OrderDao orderDao;
    @Autowired
    private OrderDetailDao orderDetailDao;
    @Autowired
    private JdbcTemplate jdbc;

    public Page<Order> findByList(final Order order) {
        Pageable pageable = PageRequest.of(order.getPage(), order.getPageSize(), Sort.Direction.DESC, ("createtime"));
        return orderDao.findAll(new Specification<Order>() {
            private static final long serialVersionUID = -1396496630802017658L;

            @Override
            public Predicate toPredicate(Root<Order> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Path<String> orderNumber = root.get("orderNumber");
                Path<String> customer = root.get("customer");
                //构造查询条件
                List<Predicate> list = new ArrayList<Predicate>();
                Predicate[] predicateA = new Predicate[list.size()];
                Predicate predicateAnd = cb.and(list.toArray(predicateA));

                if (StringUtils.isNotEmpty(order.getOrderNumber())) {
                    List<Predicate> list2 = new ArrayList<>();
                    list2.add(cb.like(orderNumber, "%" + order.getOrderNumber() + "%"));
                    list2.add(cb.like(customer, "%" + order.getCustomer() + "%"));
                    Predicate[] predicateO = new Predicate[list2.size()];
                    Predicate predicateOr = cb.or(list2.toArray(predicateO));
                    return query.where(predicateAnd, predicateOr).getRestriction();
                } else {
                    return predicateAnd;
                }
            }
        }, pageable);
    }

    @Transactional
    public void save(Order order) {
        List<OrderDetail> orderDetailList = order.getOrderDetailList();
        order.setOrderNumber(Tools.getDateAll() + Tools.random(6));
        orderDao.save(order);

        //订单详情
        String sql = "insert into t_breed_order_detail (id,last_step,order_id,title,price,number,money,company_id) values (?,?,?,?,?,?,?,?)";
        List<Object[]> batchArgs = new ArrayList<Object[]>();
        for (OrderDetail orderDetail : orderDetailList) {
            batchArgs.add(new Object[]{UUID.randomUUID().toString().replaceAll("-", ""), order.getLastStep(), order.getId(), orderDetail.getTitle(),
                    orderDetail.getPrice(), orderDetail.getNumber(), orderDetail.getMoney(), UserAuthUtil.getLoginUser().getCompanyId()});
        }
        jdbc.batchUpdate(sql, batchArgs);
    }

    public Order findById(String id) {
        Order order = orderDao.findById(id);
        if (order == null) {
            throw new BusinessException("A0001", "数据错误");
        }
        order.setOrderDetailList(orderDetailDao.findByOrderId(id));
        return order;
    }

    @Transactional
    public void delete(String id) {
        orderDao.deleteById(id);
        orderDetailDao.deleteByOrderId(id);
    }
}
